import requests
from fake_useragent import UserAgent
import time
import json
import warnings
import pandas as pd
import matplotlib.pyplot as plt
import urllib.request
openhead=urllib.request.build_opener()
openhead.addheaders = [("User-Agent", "Mozilla/5.0")]
urllib.request.install_opener(openhead)



warnings.filterwarnings("ignore")
ua = UserAgent()


# def get_weekly_data(number):
#     headers = {'User-Agent': ua.random}
#     url = f'https://api.bilibili.com/x/web-interface/popular/series/one?number={number}'
#     response = requests.get(url, headers=headers)
#     if response.status_code == 200:
#         return response.json()
#     else:
#         time.sleep(5)  # 等待5秒后重试
#         return get_weekly_data(number)
#
#
# def main():
#     for number in range(237, 278):  # 我们要爬取某期的数据，可以更改
#         data = get_weekly_data(number)
#         with open(f'datas/weekly_data_{number}.json', 'w', encoding='utf-8') as f:
#             json.dump(data, f, ensure_ascii=False)
#         time.sleep(1)  # 避免请求过于频繁
#
#
# if __name__ == '__main__':
#     main()

#
def clean_data(file_path):
    with open(file_path, 'r', encoding='utf-8') as f:
        my_df = json.load(f)
    # print(my_df)
    # 选择有价值字段
    videos = my_df['data']['list']
    print(videos[0])
    all_df = pd.DataFrame()
    a=1
    # 清洗出所需的数据
    for em in videos:
        a=a+1
        df = pd.DataFrame(em['stat'], columns=['aid', 'view', 'danmaku', 'reply',
                                       'favorite', 'coin', 'share', 'now_rank',
                                       'his_rank', 'like', 'dislike', 'vt', 'vv1'],
                          index=[a])
        df['up_name']=em['owner']['name']
        df['title_name']=em['title']
        df['topic'] = em['tname']
        df['fre'] = [1]
        all_df = pd.concat([all_df, df], ignore_index=True)


    return all_df


# 合并所有清洗后的数据
all_data = pd.DataFrame()
for number in range(277, 278):
    file_path = f'datas/weekly_data_{number}.json'
    df = clean_data(file_path)
    df.set_index(['aid'], inplace=True)
    print(df)
    all_data = pd.concat([all_data, df], ignore_index=True)
all_data.to_csv('data.csv')
# print(all_data)
# 分析各收录视频的基本播放情况





# 读取CSV文件
df = pd.read_csv('data.csv')


# 定义一个函数来将标题按每6个字符换行
def wrap_title(title, char_limit=6):
    words = []
    words = [title[i:i + char_limit] for i in range(0, len(title), char_limit)]
    return '\n'.join(words)


plt.rcParams["font.sans-serif"] = ["Microsoft YaHei"]  # 设置中文显示字体

# 按照danmaku列的值从大到小排序
sorted_df = df.sort_values(by='danmaku', ascending=False)
# 取出弹幕数前十名的视频
top_10 = sorted_df.head(10)
top_10['wrapped_title'] = top_10['title_name'].apply(wrap_title)
# 绘制柱状图
plt.figure(figsize=(20, 12), facecolor='#EFECDD')  # 调整图表大小以适应换行后的标题
plt.bar(top_10['wrapped_title'], top_10['danmaku'], color='#27DEB4')
plt.title('弹幕数最多的视频前十名', fontsize=30, fontweight='bold', fontname='Microsoft YaHei')
plt.ylabel('弹幕数', fontsize=20, fontweight='bold', fontname='Microsoft YaHei')
# 需要调整x轴的tick_params来避免标签与柱状图重叠
plt.gca().set_xticklabels(top_10['wrapped_title'], rotation=0, ha="center", fontsize=15, fontweight='bold')
plt.gca().tick_params(axis='x', which='major', pad=15)  # 增加x轴标签与轴线的距离
ax = plt.gca()  # 获取当前坐标轴
ax.set_facecolor('#EFECDD')  # 设置坐标轴的背景颜色
plt.savefig('弹幕数最多的视频前十名', dpi=800, transparent=False, bbox_inches='tight')
# 显示图表
plt.tight_layout()  # 自动调整布局
plt.show()


# 按'favorite'列的值从大到小排序
sorted_df = df.sort_values(by='favorite', ascending=False)
# 选择前10个视频
top_10 = sorted_df.head(10)
top_10['wrapped_title'] = top_10['title_name'].apply(wrap_title)
# 设置图表大小
plt.figure(figsize=(20, 12), facecolor='#EFECDD')

# 绘制柱状图
plt.bar(top_10['wrapped_title'], top_10['favorite'], color='#D64912')

# 设置图表标题和坐标轴标签
plt.title('收藏数前十名视频的柱状图', fontsize=30, fontweight='bold', fontname='Microsoft YaHei')
plt.ylabel('收藏数', fontsize=20, fontweight='bold', fontname='Microsoft YaHei')
plt.gca().set_xticklabels(top_10['wrapped_title'], rotation=0, ha="center", fontsize=15, fontweight='bold')
ax = plt.gca()  # 获取当前坐标轴
ax.set_facecolor('#EFECDD')  # 设置坐标轴的背景颜色
plt.savefig('收藏数最多的视频前十名', dpi=800, transparent=False, bbox_inches='tight')
# 显示图表
plt.tight_layout()  # 自动调整子图参数, 使之填充整个图像区域
plt.show()


# 按'reply'列的值从大到小排序
sorted_df = df.sort_values(by='reply', ascending=False)
# 选择前10个视频
top_10 = sorted_df.head(10)
top_10['wrapped_title'] = top_10['title_name'].apply(wrap_title)
# 设置图表大小
plt.figure(figsize=(20, 12), facecolor='#EFECDD')

# 绘制柱状图
plt.bar(top_10['wrapped_title'], top_10['reply'], color='#DE84F0')

# 设置图表标题和坐标轴标签
plt.title('评论数前十名视频的柱状图', fontsize=30, fontweight='bold', fontname='Microsoft YaHei')
plt.ylabel('评论数', fontsize=20, fontweight='bold', fontname='Microsoft YaHei')
plt.gca().set_xticklabels(top_10['wrapped_title'], rotation=0, ha="center", fontsize=15, fontweight='bold')
ax = plt.gca()  # 获取当前坐标轴
ax.set_facecolor('#EFECDD')  # 设置坐标轴的背景颜色
plt.savefig('评论数最多的视频前十名', dpi=800, bbox_inches='tight')
# 显示图表
plt.tight_layout()  # 自动调整子图参数, 使之填充整个图像区域
plt.show()


# 按'coin'列的值从大到小排序
sorted_df = df.sort_values(by='coin', ascending=False)
# 选择前10个视频
top_10 = sorted_df.head(10)
top_10['wrapped_title'] = top_10['title_name'].apply(wrap_title)
# 设置图表大小
plt.figure(figsize=(20, 12), facecolor='#EFECDD')

# 绘制柱状图
plt.bar(top_10['wrapped_title'], top_10['coin'], color='#F09495')

# 设置图表标题和坐标轴标签
plt.title('投币数前十名视频的柱状图', fontsize=30, fontweight='bold', fontname='Microsoft YaHei')
plt.ylabel('投币数', fontsize=20, fontweight='bold', fontname='Microsoft YaHei')
plt.gca().set_xticklabels(top_10['wrapped_title'], rotation=0, ha="center", fontsize=15, fontweight='bold')
ax = plt.gca()  # 获取当前坐标轴
ax.set_facecolor('#EFECDD')  # 设置坐标轴的背景颜色
plt.savefig('投币数最多的视频前十名', dpi=800, transparent=False, bbox_inches='tight')
# 显示图表
plt.tight_layout()  # 自动调整子图参数, 使之填充整个图像区域
plt.show()


# 按'view'列的值从大到小排序
sorted_df = df.sort_values(by='view', ascending=False)
# 选择前10个视频
top_10 = sorted_df.head(10)
top_10['wrapped_title'] = top_10['title_name'].apply(wrap_title)
# 设置图表大小
plt.figure(figsize=(20, 12), facecolor='#EFECDD')

# 绘制柱状图
plt.bar(top_10['wrapped_title'], top_10['view'], color='#59C4A1')

# 设置图表标题和坐标轴标签
plt.title('播放量前十名视频的柱状图', fontsize=30, fontweight='bold', fontname='Microsoft YaHei')
plt.ylabel('播放量', fontsize=20, fontweight='bold', fontname='Microsoft YaHei')
plt.gca().set_xticklabels(top_10['wrapped_title'], rotation=0, ha="center", fontsize=15, fontweight='bold')
ax = plt.gca()  # 获取当前坐标轴
ax.set_facecolor('#EFECDD')  # 设置坐标轴的背景颜色
plt.savefig('播放量最多的视频前十名', dpi=800, transparent=False, bbox_inches='tight')
# 显示图表
plt.tight_layout()  # 自动调整子图参数, 使之填充整个图像区域
plt.show()


# 按'share'列的值从大到小排序
sorted_df = df.sort_values(by='share', ascending=False)
# 选择前10个视频
top_10 = sorted_df.head(10)
top_10['wrapped_title'] = top_10['title_name'].apply(wrap_title)
# 设置图表大小
plt.figure(figsize=(20, 12), facecolor='#EFECDD')

# 绘制柱状图
plt.bar(top_10['wrapped_title'], top_10['share'], color='#4ECCCC')

# 设置图表标题和坐标轴标签
plt.title('分享前十名视频的柱状图', fontsize=30, fontweight='bold', fontname='Microsoft YaHei')
plt.ylabel('分享次数', fontsize=20, fontweight='bold', fontname='Microsoft YaHei')
plt.gca().set_xticklabels(top_10['wrapped_title'], rotation=0, ha="center", fontsize=15, fontweight='bold')
ax = plt.gca()  # 获取当前坐标轴
ax.set_facecolor('#EFECDD')  # 设置坐标轴的背景颜色
plt.savefig('分享最多的视频前十名', dpi=800, transparent=False, bbox_inches='tight')
# 显示图表
plt.tight_layout()  # 自动调整子图参数, 使之填充整个图像区域
plt.show()



# 按'like'列的值从大到小排序
sorted_df = df.sort_values(by='like', ascending=False)
# 选择前10个视频
top_10 = sorted_df.head(10)
top_10['wrapped_title'] = top_10['title_name'].apply(wrap_title)
# 设置图表大小
plt.figure(figsize=(20, 12), facecolor='#EFECDD')

# 绘制柱状图
plt.bar(top_10['wrapped_title'], top_10['like'], color='#4A61CC', )
# 设置图表标题和坐标轴标签
plt.title('点赞前十名视频的柱状图', fontsize=30, fontweight='bold', fontname='Microsoft YaHei')
plt.ylabel('点赞次数', fontsize=20, fontweight='bold', fontname='Microsoft YaHei')
plt.gca().set_xticklabels(top_10['wrapped_title'], rotation=0, ha="center", fontsize=15, fontweight='bold')
ax = plt.gca()  # 获取当前坐标轴
ax.set_facecolor('#EFECDD')  # 设置坐标轴的背景颜色
plt.savefig('点赞最多的视频前十名', dpi=800, transparent=False, bbox_inches='tight')
# 显示图表
plt.tight_layout()  # 自动调整子图参数, 使之填充整个图像区域
plt.show()


###########################################################


# 按照danmaku列的值从大到小排序
sorted_df = df.sort_values(by='danmaku', ascending=False)
# 取出弹幕数前十名的视频
top_10 = sorted_df.head(10)
# 绘制柱状图
plt.figure(figsize=(20, 12), facecolor='#EFECDD')  # 调整图表大小以适应换行后的标题
plt.bar(top_10['up_name'], top_10['danmaku'], color='#27DEB4')
plt.title('弹幕数最多的up主前十名', fontsize=30, fontweight='bold', fontname='Microsoft YaHei')
plt.ylabel('弹幕数', fontsize=20, fontweight='bold', fontname='Microsoft YaHei')

# 由于换行后标题可能占用更多空间，需要调整x轴的tick_params来避免标签与柱状图重叠
plt.gca().set_xticklabels(top_10['up_name'], rotation=0, ha="center", fontsize=15, fontweight='bold')
plt.gca().tick_params(axis='x', which='major', pad=15)  # 增加x轴标签与轴线的距离
ax = plt.gca()  # 获取当前坐标轴
ax.set_facecolor('#EFECDD')  # 设置坐标轴的背景颜色
plt.savefig('弹幕数最多的up主前十名', dpi=800, transparent=False, bbox_inches='tight')
# 显示图表
plt.tight_layout()  # 自动调整布局
plt.show()


# 按照favorite列的值从大到小排序
sorted_df = df.sort_values(by='favorite', ascending=False)
# 取出弹幕数前十名的视频
top_10 = sorted_df.head(10)
# 绘制柱状图
plt.figure(figsize=(20, 12), facecolor='#EFECDD')  # 调整图表大小以适应换行后的标题
plt.bar(top_10['up_name'], top_10['favorite'], color='#D64912')
plt.title('收藏数最多的up主前十名', fontsize=30, fontweight='bold', fontname='Microsoft YaHei')
plt.ylabel('收藏数', fontsize=20, fontweight='bold', fontname='Microsoft YaHei')

# 调整x轴的tick_params来避免标签与柱状图重叠
plt.gca().set_xticklabels(top_10['up_name'], rotation=0, ha="center", fontsize=15, fontweight='bold')
plt.gca().tick_params(axis='x', which='major', pad=15)  # 增加x轴标签与轴线的距离
ax = plt.gca()  # 获取当前坐标轴
ax.set_facecolor('#EFECDD')  # 设置坐标轴的背景颜色
plt.savefig('收藏数最多的up主前十名', dpi=800, transparent=False, bbox_inches='tight')
# 显示图表
plt.tight_layout()  # 自动调整布局
plt.show()


# 按照reply列的值从大到小排序
sorted_df = df.sort_values(by='reply', ascending=False)
# 取出弹幕数前十名的视频
top_10 = sorted_df.head(10)
# 绘制柱状图
plt.figure(figsize=(20, 12), facecolor='#EFECDD')  # 调整图表大小以适应换行后的标题
plt.bar(top_10['up_name'], top_10['reply'], color='#DE84F0')
plt.title('评论数最多的up主前十名', fontsize=30, fontweight='bold', fontname='Microsoft YaHei')
plt.ylabel('收藏数', fontsize=20, fontweight='bold', fontname='Microsoft YaHei')

# 调整x轴的tick_params来避免标签与柱状图重叠
plt.gca().set_xticklabels(top_10['up_name'], rotation=0, ha="center", fontsize=15, fontweight='bold')
plt.gca().tick_params(axis='x', which='major', pad=15)  # 增加x轴标签与轴线的距离
ax = plt.gca()  # 获取当前坐标轴
ax.set_facecolor('#EFECDD')  # 设置坐标轴的背景颜色
plt.savefig('评论数最多的up主前十名', dpi=800, transparent=False, bbox_inches='tight')
# 显示图表
plt.tight_layout()  # 自动调整布局
plt.show()


# 按照coin列的值从大到小排序
sorted_df = df.sort_values(by='coin', ascending=False)
# 取出弹幕数前十名的视频
top_10 = sorted_df.head(10)
# 绘制柱状图
plt.figure(figsize=(20, 12), facecolor='#EFECDD')  # 调整图表大小以适应换行后的标题
plt.bar(top_10['up_name'], top_10['coin'], color='#F09495')
plt.title('视频投币数最多的up主前十名', fontsize=30, fontweight='bold', fontname='Microsoft YaHei')
plt.ylabel('视频投币数', fontsize=20, fontweight='bold', fontname='Microsoft YaHei')

# 调整x轴的tick_params来避免标签与柱状图重叠
plt.gca().set_xticklabels(top_10['up_name'], rotation=0, ha="center", fontsize=15, fontweight='bold')
plt.gca().tick_params(axis='x', which='major', pad=15)  # 增加x轴标签与轴线的距离
ax = plt.gca()  # 获取当前坐标轴
ax.set_facecolor('#EFECDD')  # 设置坐标轴的背景颜色
plt.savefig('视频投币数最多的up主前十名', dpi=800, transparent=False, bbox_inches='tight')
# 显示图表
plt.tight_layout()  # 自动调整布局
plt.show()


# 按照view列的值从大到小排序
sorted_df = df.sort_values(by='view', ascending=False)
# 取出弹幕数前十名的视频
top_10 = sorted_df.head(10)
# 绘制柱状图
plt.figure(figsize=(20, 12), facecolor='#EFECDD')  # 调整图表大小以适应换行后的标题
plt.bar(top_10['up_name'], top_10['view'], color='#59C4A1')
plt.title('视频播放量最多的up主前十名', fontsize=30, fontweight='bold', fontname='Microsoft YaHei')
plt.ylabel('视频播放量', fontsize=20, fontweight='bold', fontname='Microsoft YaHei')

# 调整x轴的tick_params来避免标签与柱状图重叠
plt.gca().set_xticklabels(top_10['up_name'], rotation=0, ha="center", fontsize=15, fontweight='bold')
plt.gca().tick_params(axis='x', which='major', pad=15)  # 增加x轴标签与轴线的距离
ax = plt.gca()  # 获取当前坐标轴
ax.set_facecolor('#EFECDD')  # 设置坐标轴的背景颜色
plt.savefig('视频播放量最多的up主前十名', dpi=800, transparent=False, bbox_inches='tight')
# 显示图表
plt.tight_layout()  # 自动调整布局
plt.show()


# 按照share列的值从大到小排序
sorted_df = df.sort_values(by='share', ascending=False)
# 取出弹幕数前十名的视频
top_10 = sorted_df.head(10)
# top_10['wrapped_title'] = top_10['title_name'].apply(wrap_title)
# 绘制柱状图
plt.figure(figsize=(20, 12), facecolor='#EFECDD')  # 调整图表大小以适应换行后的标题
plt.bar(top_10['up_name'], top_10['share'], color='#4ECCCC')
plt.title('视频分享最多的up主前十名', fontsize=30, fontweight='bold', fontname='Microsoft YaHei')
plt.ylabel('视频分享数', fontsize=20, fontweight='bold', fontname='Microsoft YaHei')

# 需要调整x轴的tick_params来避免标签与柱状图重叠
plt.gca().set_xticklabels(top_10['up_name'], rotation=0, ha="center", fontsize=15, fontweight='bold')
plt.gca().tick_params(axis='x', which='major', pad=15)  # 增加x轴标签与轴线的距离
ax = plt.gca()  # 获取当前坐标轴
ax.set_facecolor('#EFECDD')  # 设置坐标轴的背景颜色
plt.savefig('视频分享数最多的up主前十名', dpi=800, transparent=False, bbox_inches='tight')
# 显示图表
plt.tight_layout()  # 自动调整布局
plt.show()


# 按照like列的值从大到小排序
sorted_df = df.sort_values(by='like', ascending=False)
# 取出弹幕数前十名的视频
top_10 = sorted_df.head(10)
# top_10['wrapped_title'] = top_10['title_name'].apply(wrap_title)
# 绘制柱状图
plt.figure(figsize=(20, 12), facecolor='#EFECDD')  # 调整图表大小以适应换行后的标题
plt.bar(top_10['up_name'], top_10['like'], color='#4A61CC')
plt.title('视频点赞数最多的up主前十名', fontsize=30, fontweight='bold', fontname='Microsoft YaHei')
plt.ylabel('视频点赞数', fontsize=20, fontweight='bold', fontname='Microsoft YaHei')

# 需要调整x轴的tick_params来避免标签与柱状图重叠
plt.gca().set_xticklabels(top_10['up_name'], rotation=0, ha="center", fontsize=15, fontweight='bold')
plt.gca().tick_params(axis='x', which='major', pad=15)  # 增加x轴标签与轴线的距离
ax = plt.gca()  # 获取当前坐标轴
ax.set_facecolor('#EFECDD')  # 设置坐标轴的背景颜色
plt.savefig('视频点赞数最多的up主前十名', dpi=800, transparent=False, bbox_inches='tight')
# 显示图表
plt.tight_layout()  # 自动调整布局
plt.show()


# 合并所有清洗后的数据
all_data = pd.DataFrame()
for number in range(237, 278):
    file_path = f'datas/weekly_data_{number}.json'
    df = clean_data(file_path)
    df.set_index(['aid'],inplace=True)
    all_data = pd.concat([all_data, df], ignore_index=True)
all_data.to_csv('data1.csv')
all_data = all_data.loc[:, ['topic', 'up_name', 'fre']]
print(all_data)

plt.rcParams["font.sans-serif"] = ["Microsoft YaHei"]


# 从大到小排序话题出现次数
con_data = all_data.groupby('topic').sum()
print(con_data)
sorted_data = con_data.sort_values(by='fre', ascending=False)
# 取出弹幕数前十名的视频
top_10 = sorted_data.head(10)
# top_10['wrapped_title'] = top_10['title_name'].apply(wrap_title)

# 绘制柱状图
plt.figure(figsize=(20, 12), facecolor='#EFECDD')  # 调整图表大小以适应换行后的标题
plt.bar(top_10.index, top_10['fre'], color='#3F9394')
plt.title('话题上榜次数前十名', fontsize=30, fontweight='bold', fontname='Microsoft YaHei')
plt.ylabel('上榜次数', fontsize=20, fontweight='bold', fontname='Microsoft YaHei')

# 需要调整x轴的tick_params来避免标签与柱状图重叠
plt.gca().set_xticklabels(top_10.index, rotation=0, ha="center", fontsize=15, fontweight='bold')
plt.gca().tick_params(axis='x', which='major', pad=15)  # 增加x轴标签与轴线的距离
ax = plt.gca()  # 获取当前坐标轴
ax.set_facecolor('#EFECDD')  # 设置坐标轴的背景颜色
plt.savefig('话题上榜次数前十名', dpi=1200, transparent=False, bbox_inches='tight')
# 显示图表
plt.tight_layout()  # 自动调整布局
plt.show()


# 绘制饼状图
plt.figure(figsize=(20, 12), facecolor='#EFECDD')  # 调整图表大小以适应换行后的标题
plt.pie(top_10['fre'], labels=top_10.index, autopct='%1.1f%%', textprops={'fontsize': 20}, labeldistance=1.05,
        radius=1, startangle=90)
plt.axis('equal')
plt.title('话题上榜次数前十名占比', fontsize=30, fontweight='bold', fontname='Microsoft YaHei')
plt.savefig('话题上榜次数前十名占比', dpi=1200, transparent=False, bbox_inches='tight')
# 显示图表
plt.tight_layout()  # 自动调整布局
plt.show()


# 从大到小排序up主出现次数
con_data=all_data.groupby('up_name').sum()
#print(con_data)
sorted_data = con_data.sort_values(by='fre', ascending=False)
# 取出弹幕数前十名的视频
top_10 = sorted_data.head(10)
# top_10['wrapped_title'] = top_10['title_name'].apply(wrap_title)
# 绘制柱状图
plt.figure(figsize=(20, 12), facecolor='#EFECDD')  # 调整图表大小以适应换行后的标题
plt.bar(top_10.index, top_10['fre'], color='#C8BFE7')
plt.title('up主上榜次数前十名', fontsize=30, fontweight='bold', fontname='Microsoft YaHei')
plt.ylabel('上榜次数', fontsize=20, fontweight='bold', fontname='Microsoft YaHei')

# 需要调整x轴的tick_params来避免标签与柱状图重叠
plt.gca().set_xticklabels(top_10.index, rotation=0, ha="center", fontsize=15, fontweight='bold')
plt.gca().tick_params(axis='x', which='major', pad=15)  # 增加x轴标签与轴线的距离
ax = plt.gca()  # 获取当前坐标轴
ax.set_facecolor('#EFECDD')  # 设置坐标轴的背景颜色
plt.savefig('up主上榜次数前十名', dpi=1200, transparent=False, bbox_inches='tight')
# 显示图表
plt.tight_layout()  # 自动调整布局
plt.show()


# 绘制饼状图
plt.figure(figsize=(20, 12), facecolor='#EFECDD')  # 调整图表大小以适应换行后的标题
plt.pie(top_10['fre'], labels=top_10.index, autopct='%1.1f%%', textprops={'fontsize': 20}, radius=1)
plt.title('up主上榜次数前十名占比', fontsize=30, fontweight='bold', fontname='Microsoft YaHei')
plt.savefig('up主上榜次数前十名占比', dpi=1200, transparent=False, bbox_inches='tight')
# 显示图表
plt.tight_layout()  # 自动调整布局
plt.show()